import * as Cesium from "cesium";
import BaseDraw from "./BaseDraw";

export default class DrawPolygon extends BaseDraw {
  constructor(options) {
    super(options);
    this.currentDrawId = ""; // 每次绘制的id, 根据此id 进行entity管理
    this.labelEntity = null; // 当次绘制的-标签实例
    this.polylineEntity = null; // 当次绘制的-折线实例
    this.polygonEntry = null; // 当次绘制的-多边形实例
    this.positionList = []; // 当次绘制的笛卡尔数组
  }
  // 重置绘制中间量
  resetDraw() {
    this.currentDrawId = this.generateUUID(); // 当次绘制的-id
    this.labelEntity = null; // 当次绘制的-标签实例
    this.polylineEntity = null; // 当次绘制的-折线实例
    this.polygonEntry = null; // 当次绘制的-多边形实例
    this.positionList = []; // 当次绘制的笛卡尔数组
  }
  addEntityCollection(entity) {
    this.entityCollection.add(entity, this.currentDrawId);
  }
  getAllEntity() {
    return this.entityCollection.getAll();
  }
  // 关闭 CallbackProperty的计算，取最后一次的结果
  removeCallbackProperty() {
    if (this.labelEntity) {
      this.labelEntity.position = this.labelEntity.position.getValue();
      this.labelEntity.label.text = this.labelEntity.label.text.getValue();
    }
    if (this.polygonEntry) {
      this.polygonEntry.polygon.hierarchy =
        this.polygonEntry.polygon.hierarchy.getValue();
    }
  }
  // 生成测量 Label实体
  createLabelEntity() {
    const _this = this;
    const positionList = this.positionList;
    const entity = new Cesium.Entity({
      position: new Cesium.CallbackProperty(() => {
        if (positionList.length > 2) {
          const pointList =
            _this._coorder.cartesian3ToLonLatHeightArray(positionList); // 转化为经纬度坐标
          // 返回几何中心
          const center = _this._caculater.centerOfMass([
            [...pointList, pointList[0]],
          ]);
          return center;
        } else {
          return positionList[positionList.length - 1];
        }
      }, false),
      label: {
        text: new Cesium.CallbackProperty(() => {
          // 动态改变标签显示
          if (positionList.length > 2) {
            // 返回面积
            const pointList =
              _this._coorder.cartesian3ToLonLatHeightArray(positionList); // 转化为经纬度坐标
            const area = _this._caculater.area([[...pointList, pointList[0]]]);
            if (area > 1000000) {
              return "面积:" + (area / 1000000).toFixed(2) + "平方公里";
            } else {
              return "面积:" + area.toFixed(2) + "平方米";
            }
          } else {
            return "0";
          }
        }, false),
        font: "20px",
        color: Cesium.Color.RED,
        pixelOffset: new Cesium.Cartesian2(0, 0),
        fillColor: Cesium.Color.WHITE,
        showBackground: true,
        backgroundColor: Cesium.Color.BLUE,
      },
    });
    return entity;
  }
  // 生成辅助线实体
  createPolylineEntity() {
    const _this = this;
    const positionList = this.positionList;
    const entity = new Cesium.Entity({
      polyline: {
        positions: new Cesium.CallbackProperty(() => positionList, false),
        clampToGround: true,
        material: Cesium.Color.RED,
        width: 1,
        disableDepthTestDistance: Number.POSITIVE_INFINITY,
      },
    });
    return entity;
  }
  // 生成多边形实体
  createPolygonEntity() {
    const _this = this;
    const positionList = this.positionList;
    const entity = new Cesium.Entity({
      polygon: {
        hierarchy: new Cesium.CallbackProperty(
          () => new Cesium.PolygonHierarchy(positionList),
          false
        ),
        perPositionHeight: false,
        // extrudedHeightReference: 2,
        material: Cesium.Color.YELLOW.withAlpha(0.5),
        outline: true,
        outlineColor: Cesium.Color.RED,
        outlineWidth: 10,
        disableDepthTestDistance: Number.POSITIVE_INFINITY, // 指定将在距相机多远的距离显示此多边形。
      },
    });

    return entity;
  }
}

/**
 * 开始绘制点
 * @param {* 是否显示测量Label} showMeasureLabel
 * @param {* 是否连续绘制} continuousDraw
 */
DrawPolygon.prototype.startDraw = function (
  showMeasureLabel = true,
  continuousDraw = true
) {
  const _this = this;
  this.resetDraw(); // 重置绘制中间量
  const customType = this.customType;
  this._tip.show("单击开始绘制");
  // 左键点击事件
  this._handler.addHandelEvent(
    (event) => {
      const cartesian = this._coorder.ScreenToCartesian3(event.position); // 屏幕坐标转世界坐标
      if (!Cesium.defined(cartesian)) return;
      _this.positionList.push(cartesian.clone());
      // 新增测量标注
      if (showMeasureLabel && !_this.labelEntity) {
        _this.labelEntity = _this.createLabelEntity();
        _this.addEntityCollection(_this.labelEntity);
      }
      // 绘制多边形
      if (!_this.polygonEntry) {
        _this.polygonEntry = _this.createPolygonEntity();
        _this.addEntityCollection(_this.polygonEntry);
      }
      // 绘制时的辅助线 临时的
      if (!_this.polylineEntity) {
        _this.polylineEntity = _this.createPolylineEntity();
        _this.viewer.entities.add(_this.polylineEntity);
      }
      _this._tip.changeText("右键结束绘制");
    },
    customType,
    Cesium.ScreenSpaceEventType.LEFT_CLICK
  );
  // 鼠标移动事件
  this._handler.addHandelEvent(
    (event) => {
      if (this.polygonEntry) {
        const cartesian = this._coorder.ScreenToCartesian3(event.endPosition); // 屏幕坐标转世界坐标
        if (!Cesium.defined(cartesian)) return;
        const positionList = _this.positionList;
        if (positionList.length === 1) {
          positionList.push(cartesian.clone());
        } else if (positionList.length >= 2) {
          positionList.pop();
          positionList.push(cartesian.clone());
        }
      }
      const { x, y } = event.endPosition;
      _this._tip.moveTipDOMPosition(x, y); // 改变 TipDOM 位置
    },
    customType,
    Cesium.ScreenSpaceEventType.MOUSE_MOVE
  );
  // 右键点击事件
  this._handler.addHandelEvent(
    (event) => {
      this.endDraw();
      // 连续绘制
      if (continuousDraw) {
        this.startDraw();
      }
    },
    customType,
    Cesium.ScreenSpaceEventType.RIGHT_CLICK
  );
};

/**
 * 结束绘制点
 */
DrawPolygon.prototype.endDraw = function () {
  // 如果辅助线存在,移除辅助线
  if (this.polylineEntity) {
    this.viewer.entities.remove(this.polylineEntity);
  }
  this.removeCallbackProperty(); // 删除callback的持续计算
  this._tip.close();
  // 删除事件
  const customType = this.customType;
  this._handler.removeHandelEvnet(
    customType,
    Cesium.ScreenSpaceEventType.LEFT_CLICK
  );
  this._handler.removeHandelEvnet(
    customType,
    Cesium.ScreenSpaceEventType.MOUSE_MOVE
  );
  this._handler.removeHandelEvnet(
    customType,
    Cesium.ScreenSpaceEventType.RIGHT_CLICK
  );
  this.resetDraw(); // 重置绘制中间量
};
/**
 * 清除绘制的点
 */
DrawPolygon.prototype.removeDraw = function () {
  this.entityCollection.removeAll();
};
